/**
 *
 */
// 涉及的表名
const dbName = require("../config.js");

var dao = {};
var util = {};
// 初始化
dao.init = function(obj) {
	util = obj;
}
/**
 * 查 - 根据id获取单条记录
 * @params {String} id
 * @params {Object} fieldJson 字段显示规则
 * 调用示例
 * let orderRechargeInfo = await vk.daoCenter.orderRechargeDao.findById(id);
 */
dao.findById = async (id, fieldJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.findById({
		dbName: dbName.orderRecharge,
		id,
		fieldJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};
/**
 * 查 - 根据order_no获取单条记录
 * 调用示例
let orderInfo = await vk.daoCenter.orderRechargeDao.findByOrderNo(order_no);
 */
dao.findByOrderNo = async (order_no = "___", fieldJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.findByWhereJson({
		dbName: dbName.orderRecharge,
		whereJson: {
			order_no
		},
		fieldJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};
/**
 * 查 - 根据whereJson获取单条记录
 * @params {Object} whereJson 条件
 * @params {Object} fieldJson 字段显示规则
 * 调用示例
let orderRechargeInfo = await vk.daoCenter.orderRechargeDao.findByWhereJson({

});
 */
dao.findByWhereJson = async (whereJson, fieldJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.findByWhereJson({
		dbName: dbName.orderRecharge,
		whereJson,
		fieldJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 增 - 添加一条记录
 * @params {Object} dataJson 添加的数据
 * 调用示例
await vk.daoCenter.orderRechargeDao.add({

});
 */
dao.add = async (dataJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.add({
		dbName: dbName.orderRecharge,
		dataJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 增 - 添加多条记录
 * @params {Object} dataJson 添加的数据
 * 调用示例
await vk.daoCenter.orderRechargeDao.adds(dataArr);
 */
dao.adds = async (dataArr) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.adds({
		dbName: dbName.orderRecharge,
		dataJson: dataArr
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 删 - 删除多条记录
 * @params {Object} whereJson 条件
 * 调用示例
await vk.daoCenter.orderRechargeDao.del({

});
 */
dao.del = async (whereJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.del({
		dbName: dbName.orderRecharge,
		whereJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 删 - 据ID删除单条数据
 * @params {String} id
 * 调用示例
await vk.daoCenter.orderRechargeDao.deleteById(id);
 */
dao.deleteById = async (id) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.deleteById({
		dbName: dbName.orderRecharge,
		id
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 改 - 批量修改
 * @params {Object} whereJson 条件
 * @params {Object} dataJson 修改的数据
 * 调用示例
await vk.daoCenter.orderRechargeDao.update({
	whereJson:{

	},
	dataJson:{

	}
});
 */
dao.update = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.update({
		...obj,
		dbName: dbName.orderRecharge,
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 改 - 根据ID修改数据
 * @params {String} id
 * @params {Object} dataJson 修改的数据
 * 调用示例
await vk.daoCenter.orderRechargeDao.updateById(id, dataJson);
 */
dao.updateById = async (id, dataJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.updateById({
		dbName: dbName.orderRecharge,
		id,
		dataJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 改 - 更新并返回更新后的数据（无论条件匹配到多少条记录，只会修改第一条记录，同时返回修改后的数据）
 * @params {Object} whereJson 条件
 * @params {Object} dataJson 修改的数据
 * 调用示例
await vk.daoCenter.orderRechargeDao.updateAndReturn({
	whereJson:{

	},
	dataJson:{

	}
});
 */
dao.updateAndReturn = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.updateAndReturn({
		...obj,
		dbName: dbName.orderRecharge
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 查 - 获取记录总条数
 * @params {Object} whereJson 条件
 * 调用示例
await vk.daoCenter.orderRechargeDao.count(whereJson);
 */
dao.count = async (whereJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.count({
		dbName: dbName.orderRecharge,
		whereJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 查 - 根据id获取单条记录
 * @params {String} fieldName 需要求和的字段名
 * @params {Object} whereJson 筛选条件
 * 调用示例
let orderRechargeSum = await vk.daoCenter.orderRechargeDao.sum({
	fieldName: "",
	whereJson: {

	}
});
 */
dao.sum = async (obj) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.sum({
		...obj,
		dbName: dbName.orderRecharge,
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};


/**
 * 查 - 获取数据列表
 * 调用示例
let orderRechargeList = await vk.daoCenter.orderRechargeDao.select({
	pageIndex:1,
	pageSize:20,
	getMain:false,
	whereJson:{

	},
	fieldJson:{},
	sortArr:[{ "name":"_id", "type":"desc" }],
});
 */
dao.select = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.select({
		...obj,
		dbName: dbName.orderRecharge
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 查 - 获取数据列表
 * 调用示例
let orderRechargeList = await vk.daoCenter.orderRechargeDao.selects({
	pageIndex:1,
	pageSize:20,
	getMain:false,
	whereJson:{

	},
	fieldJson:{},
	sortArr:[{ "name":"_id", "type":"desc" }],
	// 副表列表
	foreignDB:[
		{
			dbName:"副表表名",
			localKey:"主表外键名",
			foreignKey:"副表外键名",
			as:"副表as字段",
			limit:1
		}
	]
});
 */
dao.selects = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.selects({
		...obj,
		dbName: dbName.orderRecharge
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 查 - 获取数据列表
 * 调用示例
res = await vk.daoCenter.orderRechargeDao.getTableData({ data });
 */
dao.getTableData = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.getTableData({
		...obj,
		dbName: dbName.orderRecharge
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 添加充值订单
 * @params {String} id
 * @params {Object} fieldJson 字段显示规则
 * 调用示例
let orderId = await vk.daoCenter.orderRechargeDao.addOrder({
	userInfo,
	order_no,
	payment_amount, // 付款金额
	recharge_balance, // 余额数量
});
 */
dao.addOrder = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	let {
		userInfo,
		order_no,
		payment_amount,
		recharge_balance,
		order_type = 0, // 0 余额充值（暂只支持余额充值）
	} = obj;
	let dataJson = {
		status: 0,
		order_type,
		user_id: userInfo._id,
		inviter_uid: userInfo.inviter_uid,
		buyer_info: {
			_id: userInfo._id,
			nickname: userInfo.nickname,
			avatar: userInfo.avatar,
		},
		order_no,
		payment_amount,
		refund_amount: 0,
		recharge_balance
	};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.add({
		dbName: dbName.orderRecharge,
		dataJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 改 - 修改为已支付
 * @params {Object} whereJson 条件
 * @params {Object} dataJson 修改的数据
 * 调用示例
await vk.daoCenter.orderRechargeDao.orderPay({
	order_no,
	transaction_id,
	pay_type,
	platform
});
 */
dao.orderPay = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	let time = Date.now();
	let {
		order_no,
		transaction_id,
		pay_type,
		platform
	} = obj;
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.updateAndReturn({
		dbName: dbName.orderRecharge,
		whereJson: {
			order_no,
			status: 0
		},
		dataJson: {
			status: 1,
			pay_time: time,
			pay_type,
			platform,
			transaction_id
		}
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};


/**
 * 改 - 订单退款
 * 调用示例
await vk.daoCenter.orderRechargeDao.orderRefund({
	_id, // 充值订单id
	refund_amount, // 退款金额
	refund_desc, // 退款描述
	oper_user, // 操作人
});
 */
dao.orderRefund = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = { code: 0, msg: "" };
	let time = Date.now();
	let {
		_id, // 充值订单id
		refund_amount, // 退款金额
		refund_desc = "商家主动退款", // 退款描述
		oper_user, // 操作人
	} = obj;
	if (vk.pubfn.isNull(_id)) return { code: -1, msg: "id不能为空" };
	let orderInfo = await vk.daoCenter.orderRechargeDao.findById(_id);
	if (vk.pubfn.isNull(orderInfo)) return { code: -1, msg: "充值订单未找到" };
	if (orderInfo.status == -1) return { code: -1, msg: "订单已退款" };
	if (orderInfo.status == 0) return { code: -1, msg: "订单未付款" };
	if (orderInfo.status !== 1) return { code: -1, msg: "订单状态不支持退款" };
	let maxRefundAmount = orderInfo.payment_amount - orderInfo.refund_amount;
	if (refund_amount > maxRefundAmount) return { code: -1, msg: `当前最大可退金额【${vk.pubfn.priceFilter(maxRefundAmount)}】元` };
	let userInfo = await vk.daoCenter.userDao.findById(orderInfo.user_id);
	if (userInfo.account_balance.balance < refund_amount) return { code: -1, msg: `用户余额不足${vk.pubfn.priceFilter(refund_amount)}，无法退款` };
	let { refund_num = 0 } = orderInfo;
	let refund_no = `${orderInfo.order_no}-${refund_num+1}`;
	let dataJson = {
		refund_num: _.inc(1),
		refund_amount: _.inc(refund_amount),
		refund_time: time,
		refund_list: _.push({
			refund_no,
			refund_amount,
			refund_desc,
			refund_time: time,
			oper_uid: oper_user._id,
			oper_nickname: oper_user.nickname
		})
	};
	// 计算是否已全部退款
	let isFullRefund = refund_amount === maxRefundAmount ? 1 : 0;
	if (isFullRefund) {
		dataJson["status"] = -1; // 全额退款
	}
	// 开启事务
	const transaction = await vk.baseDao.startTransaction();
	try {
		// 这里写数据库语句
		let orderInfo = await vk.baseDao.updateAndReturn({
			db: transaction,
			dbName: dbName.orderRecharge,
			whereJson: {
				_id,
				status: 1
			},
			dataJson
		});
		if (!orderInfo) return { code: -1, msg: "退款失败，请重试" };
		let maxRefundAmount = orderInfo.payment_amount - orderInfo.refund_amount;
		if (maxRefundAmount < 0) {
			// 事务回滚
			await transaction.rollback();
			return { code: -1, msg: "退款失败，超出最大可退款金额" };
		}
		// 扣除用户余额，扣除量 = 退款金额 / 当时付款金额 * 充值余额数量
		let refund_balance = vk.pubfn.toDecimal(refund_amount / orderInfo.payment_amount * orderInfo.recharge_balance, 0)
		await vk.daoCenter.moneyDao.updateAccountBalanceForTransaction({
			db: transaction,
			user_id: orderInfo.user_id,
			value: refund_balance, // 此值始终为正整数 100=1元
			isAdd: false, // true 增加 false 减少
			no: orderInfo.order_no,
			title: `充值退款`,
			comment: ``,
			add_type: 4, // 1 人工录入 2 用户线上充值 3 消费 4 退款 5 转账 6 余额转换 7 奖励发放 8 解锁 9 提现 10 提现拒绝后返还
			updateTotal: true,
		});
		// 第三方支付发起退款
		let refundRes = await vk.vkPay.refund({
			out_trade_no: orderInfo.order_no,
			refund_desc: refund_desc.length > 80 ? refund_desc.substring(0, 75) + "..." : refund_desc,
			refund_fee: refund_amount
		});
		console.log('refundRes: ', refundRes)
		if (refundRes.code !== 0) {
			// 事务回滚
			await transaction.rollback();
			return refundRes;
		}
		res.msg = "退款成功";
		// 提交事务
		await transaction.commit();
		console.log(`transaction succeeded`);
	} catch (err) {
		// 事务回滚
		return await vk.baseDao.rollbackTransaction({
			db: transaction,
			err
		});
	}
	return res;
};


module.exports = dao;
